import {BasicLayoutProps, PageLoading, SettingDrawer, Settings as LayoutSettings} from '@ant-design/pro-layout';
// @ts-ignore
import {history, Link, RunTimeLayoutConfig} from 'umi';
import RightContent from '@/components/RightContent';
import Footer from '@/components/Footer';
import defaultSettings from '../config/defaultSettings';
import {CODE_MESSAGE, SYS_CONFIG} from "@/utils/constants";
import {message, notification} from "antd";
import {RequestOptionsInit} from "umi-request";
import {isSuccessful} from "@/utils/utils";
// @ts-ignore
import {RequestConfig} from "@@/plugin-request/request";
import {MenuDataItem} from "@umijs/route-utils";
import {
  BookOutlined,
  HomeOutlined,
  LinkOutlined,
  PicLeftOutlined,
  SettingOutlined,
  SmileOutlined,
  UserOutlined
} from "@ant-design/icons";
import {OpUser} from "@/services/api-functions";

const MENU_ICON_ENUMS = {
  smile: <SmileOutlined/>,
  home: <HomeOutlined/>,
  picLeft: <PicLeftOutlined/>,
  setting: <SettingOutlined/>,
  user: <UserOutlined/>,
}

const isDev = process.env.NODE_ENV === 'development';
const loginPath = '/user/login';

/** 获取用户信息比较慢的时候会展示一个 loading */
export const initialStateConfig = {
  loading: <PageLoading/>,
};

/**
 * @see  https://umijs.org/zh-CN/plugins/plugin-initial-state
 * */
export async function getInitialState(): Promise<{
  settings?: Partial<LayoutSettings>;
  currentUser?: any;
  loading?: boolean;
  fetchUserInfo?: () => Promise<any | undefined>;
}> {
  const fetchUserInfo = async () => {
    try {
      return await OpUser.currentUser();
    } catch (error) {
      history.push(loginPath);
    }
    return undefined;
  };
  // 如果是登录页面，不执行
  if (history.location.pathname !== loginPath) {
    const currentUser = await fetchUserInfo();
    return {
      fetchUserInfo,
      currentUser,
      settings: defaultSettings,
    };
  }
  return {
    fetchUserInfo,
    settings: defaultSettings,
  };
}

/** 异常处理程序 */
const errorHandler = (error: { response: Response }): Response => {
  const {response} = error;
  if (response && response.status) {
    const errorText = CODE_MESSAGE[response.status] || response.statusText;
    const {status, url} = response;

    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    });
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常，无法连接服务器',
      message: '网络异常',
    });
  }
  return response;
};

const authHeaderInterceptor = (url: string, options: RequestOptionsInit) => {
  // TODO 请求前的统一封装（加公共参数、做公共校验、加公共body。。。）
  // eslint-disable-next-line @typescript-eslint/naming-convention
  const TOKEN = localStorage.getItem(SYS_CONFIG.LOCAL_USER_TOKEN);

  let headers = {
    ...options.headers,
  };
  if (TOKEN) {
    headers = {
      ...options.headers,
      Accept: 'application/json',
      [SYS_CONFIG.USER_TOKEN]: TOKEN,
    };
  }
  return {
    url: `${url}`,
    options: {...options, interceptors: true, headers},
  };
};

const responseInterceptors = (response: Response) => {

  response.clone().json().then((res) => {
    if (isSuccessful(res)) {
      // TODO 服务器响应的统一封装
      const token = response.headers.get(SYS_CONFIG.USER_TOKEN);
      if (token) {
        localStorage.setItem(SYS_CONFIG.LOCAL_USER_TOKEN, token);
      }
    } else {
      message.error(res.msg)
    }
  })

  return response;
};

export const request: RequestConfig = {
  errorHandler,
  // 新增自动添加AccessToken的请求前拦截器
  requestInterceptors: [authHeaderInterceptor],
  responseInterceptors: [responseInterceptors],
};

const renderMenuData = (menuData: any) => {

  const {name, path, icon, component, children, hideInMenu} = menuData

  const menu: MenuDataItem = {name, path, hideInMenu, icon: MENU_ICON_ENUMS[icon ?? 'smile']}

  if (component) {
    menu.component = component
  }

  if (children && children.length > 0) {
    menu.routes = children.map((item: any) => renderMenuData(item))
  }

  return menu
}

// ProLayout 支持的api https://procomponents.ant.design/components/layout
// @ts-ignore
export const layout: RunTimeLayoutConfig = ({initialState, setInitialState}) => {
  return {
    rightContentRender: () => <RightContent/>,
    disableContentMargin: false,
    waterMarkProps: {
      content: initialState?.currentUser?.name,
    },
    footerRender: () => <Footer/>,
    onPageChange: () => {
      const {location} = history;
      // 如果没有登录，重定向到 login
      if (!initialState?.currentUser && location.pathname !== loginPath) {
        history.push(loginPath);
      }
    },
    links: isDev
      ? [
        <a href="https://www.apifox.cn/apidoc/shared-7b7312c6-9d52-4558-b6b4-5058c2074a5e" target="_blank"
           rel="noreferrer">
          <LinkOutlined/>
          <span>接口文档</span>
        </a>,
        <a href="https://ant-design.gitee.io/components/overview-cn/" target="_blank" rel="noreferrer">
          <BookOutlined/>
          <span>开发组件文档</span>
        </a>,
        <a href="https://app.mockplus.cn/app/BDL9NXBIr9y/comment/qfNAcTWSk6V/KuLA02ZmgDyc" target="_blank"
           rel="noreferrer">
          <BookOutlined/>
          <span>设计原型</span>
        </a>,
        <a href="https://shimo.im/sheets/5rk9dYz2YRUbpMqx/FdtNp" target="_blank" rel="noreferrer">
          <BookOutlined/>
          <span>反馈意见</span>
        </a>,
      ]
      : [],
    // 自定义 403 页面
    // unAccessible: <div>unAccessible</div>,
    // 增加一个 loading 的状态
    childrenRender: (children: Element, props: BasicLayoutProps) => {
      // if (initialState?.loading) return <PageLoading />;
      return (
        <>
          {children}
          {!props.location?.pathname?.includes('/login') && (
            <SettingDrawer
              enableDarkTheme
              settings={initialState?.settings}
              onSettingChange={(settings) => {
                setInitialState((preInitialState: any) => ({
                  ...preInitialState,
                  settings,
                }));
              }}
            />
          )}
        </>
      );
    },
    ...initialState?.settings,
    menuHeaderRender: undefined,
    menu: {
      params: {
        userId: initialState?.currentUser?.id,
      },
      request: async (params: Record<string, any>, defaultMenuData: MenuDataItem[]) => {

        /*console.log(params, defaultMenuData)

        // initialState.currentUser 中包含了所有用户信息
        const resp = await OperateUser.queryAdminMenus()

        return isSuccessful(resp) ? (resp.data ?? []).map((i: any) => renderMenuData(i)) : [];*/
        return defaultMenuData
      },
    },

  };
};
